package es.us.lsi.daw.controllers;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import es.us.lsi.daw.dao.DAOAcceso;
import es.us.lsi.daw.util.Util;
import es.us.lsi.daw.util.Vista;


@Controller
public class ControllerSession extends DAOAcceso {

	private static final String	LST_SESSION_OBJECTS_PARAMETER_NAME	= "lstSessionObjects";
	public static final Integer	CLEAN_MODE_SPECIFIC					= 0;
	public static final Integer	CLEAN_MODE_EXCEPTION				= 1;

	@RequestMapping({ControllerGenerico.PRIVADO + "cleanAllSessionFormsAjax.do", "/cleanAllSessionFormsAjax.do"})
	public String cleanAllSessionFormsAjax(HttpServletRequest request, @RequestParam(value = "atributo", required = false) String atributo, @RequestParam(value = "modo", required = false) Integer modo) {

		if (atributo == null) {
			cleanAllSessionForms();
		} else if (modo == null || modo.equals(CLEAN_MODE_SPECIFIC)) {
			deleteSessionObject(atributo);
		} else if (modo != null && modo.equals(CLEAN_MODE_EXCEPTION)) {
			cleanAllSessionForms(atributo);
		}

		return Vista.JSON;
	}

	public static void addObjectToSession(String name, Object obj) {

		HttpSession session = null;
		List<String> lstSessionObjects = null;

		session = Util.getSessionFromContext();
		if (session != null) {
			if (session.getAttribute(LST_SESSION_OBJECTS_PARAMETER_NAME) == null) {
				session.setAttribute(LST_SESSION_OBJECTS_PARAMETER_NAME, new ArrayList<String>());
			}
			lstSessionObjects = (List<String>) session.getAttribute(LST_SESSION_OBJECTS_PARAMETER_NAME);
			if (!lstSessionObjects.contains(name)) {
				lstSessionObjects.add(name);
			}
			session.setAttribute(name, obj);
		}
	}

	public static <T> T getObjectFromSession(String name) {

		HttpSession session = null;
		T result = null;

		session = Util.getSessionFromContext();
		if (session != null) {
			result = (T) session.getAttribute(name);
		}

		return result;

	}

	public static boolean existSessionObject(String name) {

		HttpSession session = null;
		boolean result = false;

		session = Util.getSessionFromContext();
		if (session != null && session.getAttribute(name) != null) {
			result = true;
		}

		return result;

	}

	public static void deleteSessionObject(String name) {

		HttpSession session = null;
		List<String> lstSessionObjects = null;

		session = Util.getSessionFromContext();

		if (session != null) {
			if (session.getAttribute(LST_SESSION_OBJECTS_PARAMETER_NAME) != null) {
				lstSessionObjects = (List<String>) session.getAttribute(LST_SESSION_OBJECTS_PARAMETER_NAME);
				if (lstSessionObjects != null && !lstSessionObjects.isEmpty() && lstSessionObjects.contains(name)) {
					lstSessionObjects.remove(name);
				}
			}
			session.removeAttribute(name);
		}
	}

	public static void deleteManySessionObject(String[] arrayNames) {

		if (arrayNames != null && arrayNames.length > 0) {
			for (String name : arrayNames) {
				deleteSessionObject(name);
			}
		}
	}

	public static void cleanAllSessionForms() {
		cleanAllSessionForms(null);
	}

	public static void cleanAllSessionForms(String excepcion) {

		HttpSession session = null;
		List<String> lstSessionObjects = null;
		List<String> lstSessionObjectsCopy = null;

		session = Util.getSessionFromContext();
		if (session != null) {
			if (session.getAttribute(LST_SESSION_OBJECTS_PARAMETER_NAME) != null) {
				lstSessionObjects = (List<String>) session.getAttribute(LST_SESSION_OBJECTS_PARAMETER_NAME);
				if (lstSessionObjects != null && !lstSessionObjects.isEmpty()) {
					lstSessionObjectsCopy = new ArrayList<String>();
					lstSessionObjectsCopy.addAll(lstSessionObjects);
					for (String objName : lstSessionObjectsCopy) {
						//El atributo excepción indica que hay que borrar todos los atributos a excepción del 
						//que coincide con el nombre de dicha variable
						if (excepcion == null || !excepcion.endsWith(objName)) {
							deleteSessionObject(objName);
						}
					}
					//Si el usuario ha introducido un atributo como excepción, deben limpiarse todas las variables
					//menos ésta última
					if (excepcion != null && !excepcion.isEmpty() && lstSessionObjects.contains(excepcion)) {
						lstSessionObjects.clear();
						lstSessionObjects.add(excepcion);
					} else {
						lstSessionObjects.clear();
					}
				}
			}
		}
	}

}

